wayland: Refactor selection ownership
authorCarlos Garnacho <carlosg@gnome.org>
Mon, 30 Nov 2015 17:35:10 +0000 (18:35 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Mon, 30 Nov 2015 19:37:25 +0000 (20:37 +0100)
Dissociate ownership from our maintenance of wl_data_source objects.
The only place where ownership must be updated together is
data_source.cancelled, for the other places GDK should take care of
setting up the right ownership, even if at a different order than
we'd expect here.

This fixes GTK+ apps on wayland being locally confused about the
current selection ownership. Because gtk_selection_add_targets()
results in a wl_data_source being created, and ownership being
updated right away, early callers of this will change the ownership
even if the widget it's being called on didn't explicitly request
the selection ownership yet.

https://bugzilla.gnome.org/show_bug.cgi?id=758660

gdk/wayland/gdkselection-wayland.c

index 9da66cb53d82e9d3320ab0e8790656c7c4e9e67c..b167c0c448dffe0e8e6b45200aca056e62902eb7 100644 (file)
@@ -795,6 +795,7 @@ data_source_cancelled (void                  *data,
   GdkWaylandSelection *wayland_selection = data;
   GdkDragContext *context;
   GdkDisplay *display;
+  GdkAtom atom;
 
   g_debug (G_STRLOC ": %s source = %p",
            G_STRFUNC, source);
@@ -802,16 +803,22 @@ data_source_cancelled (void                  *data,
   display = gdk_display_get_default ();
 
   if (source == wayland_selection->dnd_source)
-    {
-      gdk_wayland_selection_unset_data_source (display, atoms[ATOM_DND]);
+    atom = atoms[ATOM_DND];
+  else if (source == wayland_selection->clipboard_source)
+    atom = atoms[ATOM_CLIPBOARD];
+  else
+    return;
+
+  gdk_wayland_selection_unset_data_source (display, atom);
+  gdk_selection_owner_set (NULL, atom, GDK_CURRENT_TIME, TRUE);
 
+  if (source == wayland_selection->dnd_source)
+    {
       context = gdk_wayland_drag_context_lookup_by_data_source (source);
 
       if (context)
         gdk_wayland_device_unset_grab (gdk_drag_context_get_device (context));
     }
-  else if (source == wayland_selection->clipboard_source)
-    gdk_wayland_selection_unset_data_source (display, atoms[ATOM_CLIPBOARD]);
 }
 
 static const struct wl_data_source_listener data_source_listener = {
@@ -864,15 +871,9 @@ gdk_wayland_selection_get_data_source (GdkWindow *owner,
                                wayland_selection);
 
   if (is_clipboard)
-    {
-      wayland_selection->clipboard_source = source;
-      wayland_selection->clipboard_owner = owner;
-    }
+    wayland_selection->clipboard_source = source;
   else
-    {
-      wayland_selection->dnd_source = source;
-      wayland_selection->dnd_owner = owner;
-    }
+    wayland_selection->dnd_source = source;
 
   return source;
 }
@@ -892,7 +893,6 @@ gdk_wayland_selection_unset_data_source (GdkDisplay *display,
       device = gdk_device_manager_get_client_pointer (device_manager);
 
       gdk_wayland_device_set_selection (device, NULL);
-      wayland_selection->clipboard_owner = NULL;
 
       if (wayland_selection->clipboard_source)
         {
@@ -902,7 +902,6 @@ gdk_wayland_selection_unset_data_source (GdkDisplay *display,
     }
   else if (selection == atoms[ATOM_DND])
     {
-      wayland_selection->dnd_owner = NULL;
       wayland_selection->dnd_source = NULL;
     }
 }